from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QTreeWidget, 
                             QTreeWidgetItem, QPushButton, QLineEdit, QComboBox,
                             QLabel, QMenu, QMessageBox, QInputDialog)
from PyQt6.QtCore import Qt, pyqtSignal
from PyQt6.QtGui import QAction
from typing import Optional, List
from loguru import logger

from backend.script_manager import ScriptManager
from backend.models import ScriptModel, ScriptFilter, ScriptStatus, BrowserType


class ScriptListWidget(QWidget):
    """脚本列表组件"""
    
    # 信号定义
    script_selected = pyqtSignal(str)  # 脚本选中信号
    script_double_clicked = pyqtSignal(str)  # 脚本双击信号
    
    def __init__(self, script_manager: ScriptManager):
        super().__init__()
        self.script_manager = script_manager
        self.current_filter = ScriptFilter()
        
        self.init_ui()
        self.setup_connections()
        self.refresh_scripts()
    
    def init_ui(self):
        """初始化界面"""
        layout = QVBoxLayout(self)
        
        # 搜索和过滤区域
        filter_layout = QVBoxLayout()
        
        # 搜索框
        search_layout = QHBoxLayout()
        search_layout.addWidget(QLabel("搜索:"))
        self.search_input = QLineEdit()
        self.search_input.setPlaceholderText("输入脚本名称搜索...")
        search_layout.addWidget(self.search_input)
        filter_layout.addLayout(search_layout)
        
        # 过滤器
        filter_row_layout = QHBoxLayout()
        
        # 状态过滤
        filter_row_layout.addWidget(QLabel("状态:"))
        self.status_combo = QComboBox()
        self.status_combo.addItem("全部", "")
        self.status_combo.addItem("草稿", ScriptStatus.DRAFT.value)
        self.status_combo.addItem("激活", ScriptStatus.ACTIVE.value)
        self.status_combo.addItem("禁用", ScriptStatus.DISABLED.value)
        self.status_combo.addItem("归档", ScriptStatus.ARCHIVED.value)
        filter_row_layout.addWidget(self.status_combo)
        
        # 浏览器过滤
        filter_row_layout.addWidget(QLabel("浏览器:"))
        self.browser_combo = QComboBox()
        self.browser_combo.addItem("全部", "")
        self.browser_combo.addItem("Chromium", BrowserType.CHROMIUM.value)
        self.browser_combo.addItem("Firefox", BrowserType.FIREFOX.value)
        self.browser_combo.addItem("WebKit", BrowserType.WEBKIT.value)
        filter_row_layout.addWidget(self.browser_combo)
        
        filter_layout.addLayout(filter_row_layout)
        
        # 刷新按钮
        refresh_btn = QPushButton("刷新")
        refresh_btn.clicked.connect(self.refresh_scripts)
        filter_layout.addWidget(refresh_btn)
        
        layout.addLayout(filter_layout)
        
        # 脚本树形列表
        self.script_tree = QTreeWidget()
        self.script_tree.setHeaderLabels(["名称", "状态", "浏览器", "执行次数", "成功率", "更新时间"])
        self.script_tree.setRootIsDecorated(False)
        self.script_tree.setAlternatingRowColors(True)
        self.script_tree.setSelectionMode(QTreeWidget.SelectionMode.SingleSelection)
        self.script_tree.setSortingEnabled(True)
        
        # 设置列宽
        self.script_tree.setColumnWidth(0, 200)  # 名称
        self.script_tree.setColumnWidth(1, 80)   # 状态
        self.script_tree.setColumnWidth(2, 80)   # 浏览器
        self.script_tree.setColumnWidth(3, 80)   # 执行次数
        self.script_tree.setColumnWidth(4, 80)   # 成功率
        self.script_tree.setColumnWidth(5, 150)  # 更新时间
        
        layout.addWidget(self.script_tree)
        
        # 操作按钮
        buttons_layout = QHBoxLayout()
        
        self.new_btn = QPushButton("新建")
        self.duplicate_btn = QPushButton("复制")
        self.delete_btn = QPushButton("删除")
        self.export_btn = QPushButton("导出")
        
        buttons_layout.addWidget(self.new_btn)
        buttons_layout.addWidget(self.duplicate_btn)
        buttons_layout.addWidget(self.delete_btn)
        buttons_layout.addWidget(self.export_btn)
        buttons_layout.addStretch()
        
        layout.addLayout(buttons_layout)
    
    def setup_connections(self):
        """设置信号连接"""
        # 搜索和过滤
        self.search_input.textChanged.connect(self.on_filter_changed)
        self.status_combo.currentTextChanged.connect(self.on_filter_changed)
        self.browser_combo.currentTextChanged.connect(self.on_filter_changed)
        
        # 树形列表
        self.script_tree.itemSelectionChanged.connect(self.on_selection_changed)
        self.script_tree.itemDoubleClicked.connect(self.on_item_double_clicked)
        
        # 右键菜单
        self.script_tree.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
        self.script_tree.customContextMenuRequested.connect(self.show_context_menu)
        
        # 按钮
        self.new_btn.clicked.connect(self.new_script)
        self.duplicate_btn.clicked.connect(self.duplicate_script)
        self.delete_btn.clicked.connect(self.delete_script)
        self.export_btn.clicked.connect(self.export_script)
    
    def refresh_scripts(self):
        """刷新脚本列表"""
        try:
            # 获取过滤后的脚本
            scripts = self.script_manager.search_scripts(self.current_filter)
            
            # 清空树形列表
            self.script_tree.clear()
            
            # 添加脚本项
            for script in scripts:
                item = QTreeWidgetItem()
                self.update_tree_item(item, script)
                self.script_tree.addTopLevelItem(item)
            
            # 按更新时间倒序排序
            self.script_tree.sortItems(5, Qt.SortOrder.DescendingOrder)
            
            logger.info(f"已刷新脚本列表，共 {len(scripts)} 个脚本")
            
        except Exception as e:
            logger.error(f"刷新脚本列表失败: {e}")
    
    def update_tree_item(self, item: QTreeWidgetItem, script: ScriptModel):
        """更新树形项"""
        item.setText(0, script.name)
        item.setText(1, self.get_status_display(script.status))
        item.setText(2, script.browser_type.value.title())
        item.setText(3, str(script.execution_count))
        item.setText(4, f"{script.success_rate:.1%}")
        item.setText(5, script.updated_at.strftime("%Y-%m-%d %H:%M"))
        
        # 存储脚本ID
        item.setData(0, Qt.ItemDataRole.UserRole, script.id)
        
        # 设置状态颜色
        if script.status == ScriptStatus.ACTIVE:
            item.setBackground(1, Qt.GlobalColor.green)
        elif script.status == ScriptStatus.DISABLED:
            item.setBackground(1, Qt.GlobalColor.yellow)
        elif script.status == ScriptStatus.ARCHIVED:
            item.setBackground(1, Qt.GlobalColor.gray)
    
    def get_status_display(self, status: ScriptStatus) -> str:
        """获取状态显示文本"""
        status_map = {
            ScriptStatus.DRAFT: "草稿",
            ScriptStatus.ACTIVE: "激活",
            ScriptStatus.DISABLED: "禁用",
            ScriptStatus.ARCHIVED: "归档"
        }
        return status_map.get(status, "未知")
    
    def on_filter_changed(self):
        """过滤条件改变"""
        # 更新过滤条件
        self.current_filter.name = self.search_input.text().strip() or None
        
        status_value = self.status_combo.currentData()
        self.current_filter.status = ScriptStatus(status_value) if status_value else None
        
        browser_value = self.browser_combo.currentData()
        self.current_filter.browser_type = BrowserType(browser_value) if browser_value else None
        
        # 刷新列表
        self.refresh_scripts()
    
    def on_selection_changed(self):
        """选择改变事件"""
        current_item = self.script_tree.currentItem()
        if current_item:
            script_id = current_item.data(0, Qt.ItemDataRole.UserRole)
            if script_id:
                self.script_selected.emit(script_id)
    
    def on_item_double_clicked(self, item: QTreeWidgetItem, column: int):
        """项双击事件"""
        script_id = item.data(0, Qt.ItemDataRole.UserRole)
        if script_id:
            self.script_double_clicked.emit(script_id)
    
    def show_context_menu(self, position):
        """显示右键菜单"""
        item = self.script_tree.itemAt(position)
        if not item:
            return
        
        script_id = item.data(0, Qt.ItemDataRole.UserRole)
        if not script_id:
            return
        
        script = self.script_manager.get_script(script_id)
        if not script:
            return
        
        menu = QMenu(self)
        
        # 编辑
        edit_action = QAction("编辑", self)
        edit_action.triggered.connect(lambda: self.script_double_clicked.emit(script_id))
        menu.addAction(edit_action)
        
        # 复制
        duplicate_action = QAction("复制", self)
        duplicate_action.triggered.connect(self.duplicate_script)
        menu.addAction(duplicate_action)
        
        menu.addSeparator()
        
        # 状态操作
        if script.status != ScriptStatus.ACTIVE:
            activate_action = QAction("激活", self)
            activate_action.triggered.connect(lambda: self.change_script_status(script_id, ScriptStatus.ACTIVE))
            menu.addAction(activate_action)
        
        if script.status != ScriptStatus.DISABLED:
            disable_action = QAction("禁用", self)
            disable_action.triggered.connect(lambda: self.change_script_status(script_id, ScriptStatus.DISABLED))
            menu.addAction(disable_action)
        
        if script.status != ScriptStatus.ARCHIVED:
            archive_action = QAction("归档", self)
            archive_action.triggered.connect(lambda: self.change_script_status(script_id, ScriptStatus.ARCHIVED))
            menu.addAction(archive_action)
        
        menu.addSeparator()
        
        # 导出
        export_action = QAction("导出", self)
        export_action.triggered.connect(self.export_script)
        menu.addAction(export_action)
        
        # 删除
        delete_action = QAction("删除", self)
        delete_action.triggered.connect(self.delete_script)
        menu.addAction(delete_action)
        
        menu.exec(self.script_tree.mapToGlobal(position))
    
    def new_script(self):
        """新建脚本"""
        name, ok = QInputDialog.getText(self, "新建脚本", "请输入脚本名称:")
        if ok and name:
            script = ScriptModel(name=name)
            if self.script_manager.save_script(script):
                self.refresh_scripts()
                # 选中新创建的脚本
                for i in range(self.script_tree.topLevelItemCount()):
                    item = self.script_tree.topLevelItem(i)
                    if item.data(0, Qt.ItemDataRole.UserRole) == script.id:
                        self.script_tree.setCurrentItem(item)
                        break
    
    def duplicate_script(self):
        """复制脚本"""
        current_item = self.script_tree.currentItem()
        if not current_item:
            QMessageBox.warning(self, "警告", "请先选择要复制的脚本")
            return
        
        script_id = current_item.data(0, Qt.ItemDataRole.UserRole)
        if not script_id:
            return
        
        name, ok = QInputDialog.getText(self, "复制脚本", "请输入新脚本名称:")
        if ok and name:
            new_script = self.script_manager.duplicate_script(script_id, name)
            if new_script:
                self.refresh_scripts()
                QMessageBox.information(self, "成功", f"已复制脚本: {name}")
    
    def delete_script(self):
        """删除脚本"""
        current_item = self.script_tree.currentItem()
        if not current_item:
            QMessageBox.warning(self, "警告", "请先选择要删除的脚本")
            return
        
        script_id = current_item.data(0, Qt.ItemDataRole.UserRole)
        if not script_id:
            return
        
        script = self.script_manager.get_script(script_id)
        if not script:
            return
        
        reply = QMessageBox.question(
            self, "确认删除", 
            f"确定要删除脚本 '{script.name}' 吗？此操作不可撤销。",
            QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
            QMessageBox.StandardButton.No
        )
        
        if reply == QMessageBox.StandardButton.Yes:
            if self.script_manager.delete_script(script_id):
                self.refresh_scripts()
                QMessageBox.information(self, "成功", f"已删除脚本: {script.name}")
    
    def export_script(self):
        """导出脚本"""
        current_item = self.script_tree.currentItem()
        if not current_item:
            QMessageBox.warning(self, "警告", "请先选择要导出的脚本")
            return
        
        script_id = current_item.data(0, Qt.ItemDataRole.UserRole)
        if not script_id:
            return
        
        script = self.script_manager.get_script(script_id)
        if not script:
            return
        
        from PyQt6.QtWidgets import QFileDialog
        file_path, _ = QFileDialog.getSaveFileName(
            self, "导出脚本", f"{script.name}.json", "JSON文件 (*.json)"
        )
        if file_path:
            if self.script_manager.export_script(script_id, file_path):
                QMessageBox.information(self, "成功", f"已导出脚本到: {file_path}")
    
    def change_script_status(self, script_id: str, new_status: ScriptStatus):
        """改变脚本状态"""
        script = self.script_manager.get_script(script_id)
        if script:
            script.status = new_status
            if self.script_manager.save_script(script):
                self.refresh_scripts()
    
    def get_selected_script_id(self) -> Optional[str]:
        """获取当前选中的脚本ID"""
        current_item = self.script_tree.currentItem()
        if current_item:
            return current_item.data(0, Qt.ItemDataRole.UserRole)
        return None